// ripescript.cpp
// Entry point of the ripescript binary.
//
// Copyright (C) 2008  Maksim Sipos <msipos@mailc.net>
//
// This file is a part of the Ripe language project.
//
// Ripe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include "util/standard.hpp"
#include <cstdio>
#include <getopt.h>
#include <fstream>
#include "util/error.hpp"
#include "adts/intern.hpp"
#include "vm/vm.hpp"

using std::printf;
using std::ifstream;
using namespace Ripe;

void help_message(char* arg1)
{
  printf("Usage: %s [OPTIONS] FILES\n"
         "Execute Ripe VM binaries.\n"
         "\n"
         "Possible options:\n"
         "  -h, --help      Display this message.\n"
         "\n"
         "Report bugs to <msipos@mailc.net>\n", arg1);
}

int main(int argc, char** argv)
{
  // Initialize the error-reporting system.
  error_init(argv[0]);

  struct option long_options[] =
    {
      {"help", no_argument, 0, 'h'},
      {0, 0, 0, 0}
    };
  // getopt_long stores the option index here.
  int option_index = 0;

  while(true){
    int c = getopt_long(argc, argv, "h", long_options, &option_index);

    // End of long/short options, remainder of the arguments should be
    // interpreted like input files.
    if (c == EOF){
      break;
    }

    switch(c){
      case 'h':
        help_message(argv[0]);
        return 0;

      default:
       error("Parsing command-line arguments failed.");
        return 1;
    }
  }

  if (optind >= argc){
    error("No input files specified.");
    return 1;
  }

  // Instantiate the Virtual machine
  VM vm;

  int arg = optind;
  while (arg < argc){
    ifstream f(argv[arg], ifstream::in | ifstream::binary);
    if (f.fail()) {
      error("Failed opening file '%s'.", argv[arg]);
      return 1;
    }
    try {
      vm.load(&f);
    } catch (const ErrorVMFileLoad& e) {
      error("While reading file '%s': %s", argv[arg], e.what());
    }

    arg++;
  }
  return 0;
}
